import React, { useState, useEffect } from 'react';
import styled, { keyframes } from 'styled-components';
import { setIntervalImmediately } from '../utils/common';

const moveUp = (distance: number, gradient: number) => keyframes`
    0% {
        transform: translateY(100%);
        opacity: ${gradient ? 0 : 1}
    }
    50% {
 //       transform: translateY(calc(50% - ${distance}px)); /* move up */
        opacity: 1
    }
    100% {
        transform: translateY(calc(0% - ${distance}px)); /* move to center*/
        opacity: ${gradient ? 0 : 1}
    }
`;

const Container = styled.div<{ $overflow?: string }>`
    width: auto;
    height: auto;
    /* border: 1px solid #ccc; */
    display: flex;
    justify-content: center;
    overflow: ${({ $overflow }) => $overflow};
`;

const AnimatedText = styled.div<{ $duration: number, $distance: number, $gradient: number }>`
    animation: ${({ $distance, $gradient }) => moveUp($distance, $gradient)} ${({ $duration }) => $duration}s ease forwards;
    display: flex;
    justify-content: center;
    align-items: center;
`;

interface Props {
    gradient?: boolean;
    distance?: number;
    duration: number; // animation duration
    displayDuration: number; // stay duration after animation end
    loopDuration: number; // duration of one cycle, must be greater than duration + displayDuration
    element: string | React.ReactNode;
}

const AnimatedTextComponent: React.FC<Props> = ({
    duration,
    displayDuration,
    loopDuration,
    element,
    gradient = false,
    distance = 0
}) => {
    const [showText, setShowText] = useState(false);
    useEffect(() => {
        if (displayDuration + duration > loopDuration) {
            console.error('displayDuration plus duration is larger than loopDuration')
            // backup
            if (duration > loopDuration) {
                console.error('duration is larger than loopDuration')
            }
            // return;
        }

        let delayTimer: NodeJS.Timeout | undefined = undefined;
        const timer = setIntervalImmediately(() => {
            clearTimeout(delayTimer)
            setShowText(true);
            delayTimer = setTimeout(() => {
                setShowText(false)
            }, (displayDuration + duration) * 1000);
        }, loopDuration * 1000)
        return () => {
            clearInterval(timer)
            clearTimeout(delayTimer)
        }

    }, [loopDuration, displayDuration, duration])

    return (
        <Container $overflow={distance === 0 ? 'hidden' : undefined}>
            {showText && (
                <AnimatedText
                    $gradient={Number(gradient)}
                    $duration={duration}
                    $distance={distance}
                >
                    {typeof element === 'string' ? <span>{element}</span> : element}
                </AnimatedText>
            )}
        </Container>
    );
};

export default AnimatedTextComponent;
